package com.cardone.platform.common.dao;

import com.cardone.context.*;
import com.cardone.context.function.*;
import com.cardone.persistent.support.*;
import com.cardone.platform.common.dto.*;
import com.google.common.collect.*;
import lombok.*;
import lombok.extern.slf4j.*;
import org.apache.commons.collections.*;
import org.apache.commons.lang3.*;

import java.util.*;

/**
 * 实体编号
 *
 * @author yaohaitao
 */
@Getter
@Setter
@Slf4j
public class EntityCodeJdbcDao extends SimpleJdbcDao<EntityCodeDto> implements EntityCodeDao {
    public EntityCodeJdbcDao() {
        super(EntityCodeDao.SqlIds.ROOT);
    }

    @Override
    protected boolean isBlankById(EntityCodeDto dto) {
        return StringUtils.isBlank(dto.getId());
    }

    @Override
    protected void setId(EntityCodeDto dto) {
        dto.setId(UUID.randomUUID().toString());
    }

    @Override
    public String generateCode(final String id, final String typeCode, final Execution1Function<String, String> function, final Map<String, Object> parameters) {
        final String insertByNotExistsCodeSql = SqlIds.insertByNotExistsCodeFor.id() + id;

        final String readMaxCodeByCodeSql = SqlIds.readMaxCodeByCodeFor.id() + id;

        final Map<String, Object> newParameters = Maps.newHashMap();

        if (MapUtils.isNotEmpty(parameters)) {
            newParameters.putAll(parameters);
        }

        newParameters.put(Attributes.typeCode.name(), typeCode);

        String code;

        int reCount = 0;

        while (true) {
            code = ContextHolder.getBean(JdbcTemplateSupport.class).read(String.class, readMaxCodeByCodeSql, newParameters);

            newParameters.put(Attributes.id.name(), UUID.randomUUID().toString());
            newParameters.put(Attributes.code.name(), code);
            newParameters.put(Attributes.typeCode.name(), typeCode);

            if (function != null) {
                code = function.execution(code);
            }

            final int insertCount = ContextHolder.getBean(JdbcTemplateSupport.class).update(insertByNotExistsCodeSql, newParameters);

            if (insertCount > 0) {
                break;
            }

            reCount++;

            if (reCount > 100) {
                throw new DictionaryException("重试了100次也没有获取到不重复的编号");
            }
        }

        return code;
    }
}